//import com.intellij.lexer.FlexLexer;
//import com.intellij.psi.tree.IElementType;
import lexical.Token;
import lexical.TokenKind;
import java.io.FileReader;
//import sym;
%%

%class PythonLexer
//%implements FlexLexer
%unicode
%type Token
%function nextToken
%line
%public
%column

/* 可输入字符 */
InputCharacter = [^\r\n]
/* 换行符 */
LineTerminator	=	\r|\n|\r\n
/* 用户自定义标识符 */
id_pattern	=	[:jletter:] [:jletterdigit:]*

/* 单引号字符串 */
str1 = '[^(\r|\n|\r\n)]*'
/* 双引号字符串 */
str2 = \"[^(\r|\n|\r\n)]*\"
/* 字符串*/
str_pattern	=	{str1} | {str2}


/* 行尾注释 */
End_Line_Comment	=	"\#" {InputCharacter}*
/* 普通注释 */
Traditional_Comment	=	(''') [^(''')]* (''')
/* 文档注释 */
Documentation_Comment	=	(\"\"\") [^(\"\"\")]* (\"\"\")
/* 所有注释 */
comment_pattern	=	{End_Line_Comment}|{Traditional_Comment}|{Documentation_Comment}

WhiteSpace     = {LineTerminator} | [" "\t\f]
BlankSquence = [" "\t\f]*

// 十进制整数
//DecIntegerLiteral = -? [0-9]*   // 允许前导0
DecIntegerLiteral = (0+ | [1-9][0-9]*) // 不允许非0整数的前导0，但是允许多个0表示0
//DecIntegerLiteral = ^(-?[1-9]|0+$)\d*$ // 不允许非0整数的前导0，但是允许多个0表示0

// 不合法的十进制整数
ErrorDec = (0+)[0-9]*

// 浮点数指数部分
Exponent = e[+-]?[0-9]+
// 浮点数小数部分
Decimal = \.[0-9]+
// 浮点数
FloatLiteral = {DecIntegerLiteral}{Exponent} | {DecIntegerLiteral}{Decimal} | {DecIntegerLiteral}{Decimal}{Exponent}
// 复数
Complex = {FloatLiteral} [jJ]


%state STRING
%state COMMENT
%state IDENTIFIER

%{
public static void main(String[] args) throws Exception {

        FileReader reader = new FileReader("I:\\IDEA-workspace\\compiler\\src\\main\\java\\lexical\\test.py");
        PythonLexer lexer = new PythonLexer(reader);

        while (true) {
            try {
                Token token = lexer.nextToken();
                if(token == null)
                break;
                System.out.println(token);
            } catch (Exception e) {
                e.printStackTrace();
                break;
            }
        }
    }
%}

%%


<YYINITIAL> {
// 字符串
{str_pattern}           {return new Token(TokenKind.CONSTANT_STR, yytext());}
// 注释，可以不处理
{comment_pattern}       {return new Token(TokenKind.COMMENT, yytext());}
// 连续空格，返回token的值为连续空格的数量
{BlankSquence}          {return new Token(TokenKind.DELIMITER_WHITE_SPACE, String.valueOf(yytext().length()));}
// 换行
{LineTerminator}        {
          String s = yytext().
          replaceAll("\\r","\\\\r").
          replaceAll("\\n","\\\\n");
          return new Token(TokenKind.DELIMITER_LINE_TERMINATOR, s);}
// 标识符
{id_pattern}            {return new Token(TokenKind.IDENTIFIER, yytext());}
// 小数
{FloatLiteral}          {return new Token(TokenKind.CONSTANT_FLOAT, yytext());}
// 十进制整数
{DecIntegerLiteral}     {return new Token(TokenKind.CONSTANT_INT, yytext());}
// 复数
{Complex}               {return new Token(TokenKind.CONSTANT_COMPLEX, yytext());}

// 非法错误词法
{ErrorDec}              {
          // 其他业务逻辑
          return new Token(TokenKind.INVALID_TOKEN, yytext());
      }

// 算数运算符
"+"     {return new Token(TokenKind.OPERATOR_PLUS);}
"-"     {return new Token(TokenKind.OPERATOR_SUBSTRACT);}
"*"     {return new Token(TokenKind.OPERATOR_START);}
"/"     {return new Token(TokenKind.OPERATOR_DIVIDE);}
"//"    {return new Token(TokenKind.OPERATOR_FLOOR);}
"**"    {return new Token(TokenKind.OPERATOR_POWER);}
"%"     {return new Token(TokenKind.OPERATOR_MOD);}

// 赋值运算符
"="      {return new Token(TokenKind.OPERATOR_EQ);}
"+="     {return new Token(TokenKind.OPERATOR_PLUS_EQ);}
"-="     {return new Token(TokenKind.OPERATOR_SUBSTRACT_EQ);}
"*="     {return new Token(TokenKind.OPERATOR_START_EQ);}
"/="     {return new Token(TokenKind.OPERATOR_DIVIDE_EQ);}
"//="    {return new Token(TokenKind.OPERATOR_FLOOR_EQ);}
"**="    {return new Token(TokenKind.OPERATOR_POWER_EQ);}
"%="     {return new Token(TokenKind.OPERATOR_MOD_EQ);}

// 位运算符
"|"     {return new Token(TokenKind.OPERATOR_BITWISE_OR);}
"^"     {return new Token(TokenKind.OPERATOR_BITWISE_XOR);}
"&"     {return new Token(TokenKind.OPERATOR_BITWISE_AND);}
"!"     {return new Token(TokenKind.OPERATOR_BITWISE_NOT);}
"~"     {return new Token(TokenKind.OPERATOR_BITWISE_NEGATION);}
"<<"    {return new Token(TokenKind.OPERATOR_BITWISE_LMOV);}
">>"    {return new Token(TokenKind.OPERATOR_BITWISE_RMOV);}

// 关系运算符
"=="    {return new Token(TokenKind.OPERATOR_EQEQ);}
"!="    {return new Token(TokenKind.OPERATOR_NE);}
"<"     {return new Token(TokenKind.OPERATOR_LT);}
"<="    {return new Token(TokenKind.OPERATOR_LTEQ);}
">"     {return new Token(TokenKind.OPERATOR_GT);}
">="    {return new Token(TokenKind.OPERATOR_GTEQ);}
"<>"    {return new Token(TokenKind.OPERATOR_LTGT);}

// 界符
"("     {return new Token(TokenKind.DELIMITER_LPARENTHESIS);}
")"     {return new Token(TokenKind.DELIMITER_RPARENTHESIS);}
"{"     {return new Token(TokenKind.DELIMITER_LBRACE);}
"}"     {return new Token(TokenKind.DELIMITER_RBRACE);}
"["     {return new Token(TokenKind.DELIMITER_LBRACKT);}
"]"     {return new Token(TokenKind.DELIMITER_RBRACKT);}
":"     {return new Token(TokenKind.DELIMITER_COLON);}
","     {return new Token(TokenKind.DELIMITER_COMMA);}
"."     {return new Token(TokenKind.DELIMITER_DOT);}
"@"     {return new Token(TokenKind.DELIMITER_AT);}
";"     {return new Token(TokenKind.DELIMITER_SEMICOLON);}




}

// 关键字
<YYINITIAL> "False"     {return new Token(TokenKind.KEYWORD_FALSE); }
<YYINITIAL> "None"      {return new Token(TokenKind.KEYWORD_NONE); }
<YYINITIAL> "True"      {return new Token(TokenKind.KEYWORD_TRUE); }
<YYINITIAL> "and"       {return new Token(TokenKind.KEYWORD_AND); }
<YYINITIAL> "as"        {return new Token(TokenKind.KEYWORD_AS); }
<YYINITIAL> "assert"    {return new Token(TokenKind.KEYWORD_ASSERT); }
<YYINITIAL> "break"     {return new Token(TokenKind.KEYWORD_BREAK); }
<YYINITIAL> "class"     {return new Token(TokenKind.KEYWORD_CLASS); }
<YYINITIAL> "continue"  {return new Token(TokenKind.KEYWORD_CONTINUE); }
<YYINITIAL> "def"       {return new Token(TokenKind.KEYWORD_DEF); }
<YYINITIAL> "del"       {return new Token(TokenKind.KEYWORD_DEL); }
<YYINITIAL> "elif"      {return new Token(TokenKind.KEYWORD_ELIF); }
<YYINITIAL> "else"      {return new Token(TokenKind.KEYWORD_ELSE); }
<YYINITIAL> "except"    {return new Token(TokenKind.KEYWORD_EXCEPT); }
<YYINITIAL> "finally"   {return new Token(TokenKind.KEYWORD_FINALLY); }
<YYINITIAL> "for"       {return new Token(TokenKind.KEYWORD_FOR); }
<YYINITIAL> "from"      {return new Token(TokenKind.KEYWORD_FROM); }
<YYINITIAL> "global"    {return new Token(TokenKind.KEYWORD_GLOBAL); }
<YYINITIAL> "if"        {return new Token(TokenKind.KEYWORD_IF); }
<YYINITIAL> "import"    {return new Token(TokenKind.KEYWORD_IMPORT); }
<YYINITIAL> "in"        {return new Token(TokenKind.KEYWORD_IN); }
<YYINITIAL> "is"        {return new Token(TokenKind.KEYWORD_IS); }
<YYINITIAL> "lambda"    {return new Token(TokenKind.KEYWORD_LAMBDA); }
<YYINITIAL> "nonlocal"  {return new Token(TokenKind.KEYWORD_NONLOCAL); }
<YYINITIAL> "not"       {return new Token(TokenKind.KEYWORD_NOT); }
<YYINITIAL> "or"        {return new Token(TokenKind.KEYWORD_OR); }
<YYINITIAL> "pass"      {return new Token(TokenKind.KEYWORD_PASS); }
<YYINITIAL> "raise"     {return new Token(TokenKind.KEYWORD_RAISE); }
<YYINITIAL> "return"    {return new Token(TokenKind.KEYWORD_RETURN); }
<YYINITIAL> "try"       {return new Token(TokenKind.KEYWORD_TRY); }
<YYINITIAL> "while"     {return new Token(TokenKind.KEYWORD_WHILE); }
<YYINITIAL> "with"      {return new Token(TokenKind.KEYWORD_WITH); }
<YYINITIAL> "yield"     {return new Token(TokenKind.KEYWORD_YIELD); }

// 无法识别的错误
[^]    { throw new Error("Illegal character <"+yytext()+">"); }